﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls
{
    [TemplatePart(Name = "LowerThumb", Type = typeof(Thumb)), 
    StyleTypedProperty(Property = "ValidationDecoratorStyle", StyleTargetType = typeof(ValidationDecorator)), 
    TemplatePart(Name = "DecreaseRepeatButton", Type = typeof(RepeatButton)), 
    TemplateVisualState(Name = "InvalidFocused", GroupName = "ValidationStatesStates"), 
    TemplatePart(Name = "UpperThumb", Type = typeof(Thumb)), TemplatePart(Name = "IncreaseRepeatButton", Type = typeof(RepeatButton)), 
    TemplatePart(Name = "MiddleThumb", Type = typeof(Thumb)), TemplatePart(Name = "VerticalLowerThumb", Type = typeof(Thumb)), 
    TemplatePart(Name = "VerticalUpperThumb", Type = typeof(Thumb)), TemplatePart(Name = "VerticalMiddleThumb", Type = typeof(Thumb)), 
    TemplatePart(Name = "VerticalDecreaseRepeatButton", Type = typeof(RepeatButton)), TemplatePart(Name = "VerticalIncreaseRepeatButton", Type = typeof(RepeatButton)), 
    TemplatePart(Name = "HorizontalTemplate", Type = typeof(Grid)), TemplatePart(Name = "VerticalTemplate", Type = typeof(Grid)), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), TemplateVisualState(Name = "Focused", GroupName = "FocusStates"), 
    TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates"), TemplateVisualState(Name = "Valid", GroupName = "ValidationStatesStates"), 
    TemplateVisualState(Name = "InvalidUnfocused", GroupName = "ValidationStatesStates")]
    public class RangeSlider : Control
    {
        // Fields
        private double _dragValue;
        internal RepeatButton _elementDecreaseRepeatButton;
        internal Grid _elementHorizontalTemplate;
        internal RepeatButton _elementIncreaseRepeatButton;
        internal Thumb _elementLowerThumb;
        internal Thumb _elementMiddleThumb;
        internal Thumb _elementUpperThumb;
        internal RepeatButton _elementVerticalDecreaseRepeatButton;
        internal RepeatButton _elementVerticalIncreaseRepeatButton;
        internal Thumb _elementVerticalLowerThumb;
        internal Thumb _elementVerticalMiddleThumb;
        internal Grid _elementVerticalTemplate;
        internal Thumb _elementVerticalUpperThumb;
        private bool _isCoercingValue;
        private bool _isEventFiringAllowed;
        internal bool _isLoaded;
        private bool _isTrackUpdateAllowed;
        private double _middleDragValue;
        private bool _throwIsMouseOverChanged;
        private bool _throwOrientationChanged;
        internal const string DecreaseRepeatButtonElementName = "DecreaseRepeatButton";
        public static readonly DependencyProperty DelayProperty = DependencyProperty.Register("Delay", typeof(int), typeof(RangeSlider), new PropertyMetadata(300));
        public static readonly DependencyProperty FocusBrushProperty = DependencyProperty.Register("FocusBrush", typeof(Brush), typeof(RangeSlider), null);
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(RangeSlider), new PropertyMetadata(new PropertyChangedCallback(RangeSlider.OnForceMouseOverPropertyChanged)));
        internal const string HorizontalTemplateElementName = "HorizontalTemplate";
        internal const string IncreaseRepeatButtonElementName = "IncreaseRepeatButton";
        public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register("Interval", typeof(int), typeof(RangeSlider), new PropertyMetadata(50));
        public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.Register("IsFocused", typeof(bool), typeof(RangeSlider), new PropertyMetadata(new PropertyChangedCallback(RangeSlider.OnIsFocusedPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(RangeSlider), new PropertyMetadata(new PropertyChangedCallback(RangeSlider.OnIsMouseOverPropertyChanged)));
        internal const string LowerThumbElementName = "LowerThumb";
        public static readonly DependencyProperty LowerValueProperty = DependencyProperty.Register("LowerValue", typeof(double), typeof(RangeSlider), new PropertyMetadata(0.0, new PropertyChangedCallback(RangeSlider.OnLowerValuePropertyChanged)));
        public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(RangeSlider), new PropertyMetadata(100.0, new PropertyChangedCallback(RangeSlider.OnMaximumPropertyChanged)));
        internal const string MiddleThumbElementName = "MiddleThumb";
        public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(RangeSlider), new PropertyMetadata(0.0, new PropertyChangedCallback(RangeSlider.OnMinimumPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(RangeSlider), null);
        public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(RangeSlider), new PropertyMetadata(Orientation.Horizontal, new PropertyChangedCallback(RangeSlider.OnOrientationPropertyChanged)));
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(RangeSlider), null);
        public static readonly DependencyProperty SmallValueChangeProperty = DependencyProperty.Register("SmallValueChange", typeof(double), typeof(RangeSlider), new PropertyMetadata(0.1));
        internal const string UpperThumbElementName = "UpperThumb";
        public static readonly DependencyProperty UpperValueProperty = DependencyProperty.Register("UpperValue", typeof(double), typeof(RangeSlider), new PropertyMetadata(100.0, new PropertyChangedCallback(RangeSlider.OnUpperValuePropertyChanged)));
        public static readonly DependencyProperty ValidationDecoratorStyleProperty = DependencyProperty.Register("ValidationDecoratorStyle", typeof(Style), typeof(RangeSlider), null);
        public static readonly DependencyProperty ValueChangeProperty = DependencyProperty.Register("ValueChange", typeof(double), typeof(RangeSlider), new PropertyMetadata(10.0));
        internal const string VerticalDecreaseRepeatButtonElementName = "VerticalDecreaseRepeatButton";
        internal const string VerticalIncreaseRepeatButtonElementName = "VerticalIncreaseRepeatButton";
        internal const string VerticalLowerThumbElementName = "VerticalLowerThumb";
        internal const string VerticalMiddleThumbElementName = "VerticalMiddleThumb";
        internal const string VerticalTemplateElementName = "VerticalTemplate";
        internal const string VerticalUpperThumbElementName = "VerticalUpperThumb";

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event EventHandler LowerValueChanged;
        public event EventHandler<PropertyChangedEventArgs<Orientation>> OrientationChanged;
        public event EventHandler UpperValueChanged;
        public event EventHandler ValueChanged;

        // Methods
        public RangeSlider()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._throwOrientationChanged = true;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(RangeSlider);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateCommon(false);
                    this.ChangeVisualStateFocus(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.GotFocus += new RoutedEventHandler(this.Control_GotFocus);
            base.LostFocus += new RoutedEventHandler(this.Control_LostFocus);
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        private void _elementThumb_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (!e.Handled && base.IsEnabled)
            {
                bool flag = (sender == this._elementLowerThumb) || (sender == this._elementVerticalLowerThumb);
                bool flag2 = (sender == this._elementUpperThumb) || (sender == this._elementVerticalUpperThumb);
                if ((e.Key == Key.Left) || (e.Key == Key.Down))
                {
                    if (flag)
                    {
                        this.LowerValue -= this.SmallValueChange;
                    }
                    else if (flag2)
                    {
                        this.UpperValue -= this.SmallValueChange;
                    }
                }
                else if ((e.Key == Key.Right) || (e.Key == Key.Up))
                {
                    if (flag)
                    {
                        this.LowerValue += this.SmallValueChange;
                    }
                    else if (flag2)
                    {
                        this.UpperValue += this.SmallValueChange;
                    }
                }
                else if (e.Key == Key.Home)
                {
                    if (flag)
                    {
                        this.LowerValue = this.Minimum;
                    }
                    else if (flag2)
                    {
                        this.UpperValue = this.Minimum;
                    }
                }
                else if (e.Key == Key.End)
                {
                    if (flag)
                    {
                        this.LowerValue = this.Maximum;
                    }
                    else if (flag2)
                    {
                        this.UpperValue = this.Maximum;
                    }
                }
            }
        }

        private void BindTabStop(Control control)
        {
            Binding binding = new Binding().From<RangeSlider>(this, x => x.IsTabStop);
            control.SetBinding(Control.IsTabStopProperty, binding);
        }

        private void Control_GotFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = true;
        }

        private void Control_LostFocus(object sender, RoutedEventArgs e)
        {
            this.IsFocused = false;
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateFocus(bool useTransitions)
        {
            if (!this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Unfocused", useTransitions);
            }
            if (this.IsFocused)
            {
                VisualStateHelper.GoToState(this, "Focused", useTransitions);
            }
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void InitializeDecreaseRepeatButtonPart()
        {
            this._elementDecreaseRepeatButton.Click += (s, e) => this.LowerValue -= this.ValueChange;
            this._elementDecreaseRepeatButton.Delay = this.Delay;
            this._elementDecreaseRepeatButton.Interval = this.Interval;
        }

        private void InitializeIncreaseRepeatButtonPart()
        {
            this._elementIncreaseRepeatButton.Click += (s, e) => this.UpperValue += this.ValueChange;
            this._elementIncreaseRepeatButton.Delay = this.Delay;
            this._elementIncreaseRepeatButton.Interval = this.Interval;
        }

        private void InitializeLowerThumbPart()
        {
            this._elementLowerThumb.DragStarted += (s, e) => this.OnThumbDragStarted(this._elementLowerThumb, e, true);
            this._elementLowerThumb.DragDelta += (s, e) => this.OnThumbDragDelta(e, true);
            this._elementLowerThumb.KeyDown += new KeyEventHandler(this._elementThumb_KeyDown);
            this.BindTabStop(this._elementLowerThumb);
        }

        private void InitializeMiddleThumbPart()
        {
            this._elementMiddleThumb.DragStarted += delegate(object s, System.Windows.Controls.Primitives.DragStartedEventArgs e)
            {
                base.Focus();
                this._middleDragValue = this.LowerValue;
            };
            this._elementMiddleThumb.DragDelta += (s, e) => this.OnMiddleThumbDragDelta(e);
        }

        private void InitializeUpperThumbPart()
        {
            this._elementUpperThumb.DragStarted += (s, e) => this.OnThumbDragStarted(this._elementUpperThumb, e, false);
            this._elementUpperThumb.DragDelta += (s, e) => this.OnThumbDragDelta(e, false);
            this._elementUpperThumb.KeyDown += new KeyEventHandler(this._elementThumb_KeyDown);
            this.BindTabStop(this._elementUpperThumb);
        }

        private void InitializeVerticalDecreaseRepeatButtonPart()
        {
            this._elementVerticalDecreaseRepeatButton.Click += (s, e) => this.LowerValue -= this.ValueChange;
            this._elementVerticalDecreaseRepeatButton.Delay = this.Delay;
            this._elementVerticalDecreaseRepeatButton.Interval = this.Interval;
        }

        private void InitializeVerticalIncreaseRepeatButtonPart()
        {
            this._elementVerticalIncreaseRepeatButton.Click += (s, e) => this.UpperValue += this.ValueChange;
            this._elementVerticalIncreaseRepeatButton.Delay = this.Delay;
            this._elementVerticalIncreaseRepeatButton.Interval = this.Interval;
        }

        private void InitializeVerticalLowerThumbPart()
        {
            this._elementVerticalLowerThumb.DragStarted += (s, e) => this.OnThumbDragStarted(this._elementVerticalLowerThumb, e, true);
            this._elementVerticalLowerThumb.DragDelta += (s, e) => this.OnThumbDragDelta(e, true);
            this._elementVerticalLowerThumb.KeyDown += new KeyEventHandler(this._elementThumb_KeyDown);
            this.BindTabStop(this._elementVerticalLowerThumb);
        }

        private void InitializeVerticalMiddleThumbPart()
        {
            this._elementVerticalMiddleThumb.DragStarted += delegate(object s, System.Windows.Controls.Primitives.DragStartedEventArgs e)
            {
                base.Focus();
                this._middleDragValue = this.LowerValue;
            };
            this._elementVerticalMiddleThumb.DragDelta += (s, e) => this.OnMiddleThumbDragDelta(e);
        }

        private void InitializeVerticalUpperThumbPart()
        {
            this._elementVerticalUpperThumb.DragStarted += (s, e) => this.OnThumbDragStarted(this._elementVerticalUpperThumb, e, false);
            this._elementVerticalUpperThumb.DragDelta += (s, e) => this.OnThumbDragDelta(e, false);
            this._elementVerticalUpperThumb.KeyDown += new KeyEventHandler(this._elementThumb_KeyDown);
            this.BindTabStop(this._elementVerticalUpperThumb);
        }

        private void OnAfterApplyTemplate()
        {
            double defaultValue = (double)MinimumProperty.GetMetadata(typeof(RangeSlider)).DefaultValue;
            double oldValue = (double)MaximumProperty.GetMetadata(typeof(RangeSlider)).DefaultValue;
            double num3 = (double)LowerValueProperty.GetMetadata(typeof(RangeSlider)).DefaultValue;
            double num4 = (double)UpperValueProperty.GetMetadata(typeof(RangeSlider)).DefaultValue;
            this.OnMinimumChanged(defaultValue);
            this.OnMaximumChanged(oldValue);
            this.OnLowerValueChanged(num3);
            this.OnUpperValueChanged(num4);
            this.OnOrientationChanged(null, null);
            this.UpdateTrackLayout();
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementLowerThumb = this.GetTemplateChild<Thumb>("LowerThumb", true, ref errors);
            if (this._elementLowerThumb != null)
            {
                this.InitializeLowerThumbPart();
            }
            this._elementUpperThumb = this.GetTemplateChild<Thumb>("UpperThumb", true, ref errors);
            if (this._elementUpperThumb != null)
            {
                this.InitializeUpperThumbPart();
            }
            this._elementDecreaseRepeatButton = this.GetTemplateChild<RepeatButton>("DecreaseRepeatButton", true, ref errors);
            if (this._elementDecreaseRepeatButton != null)
            {
                this.InitializeDecreaseRepeatButtonPart();
            }
            this._elementIncreaseRepeatButton = this.GetTemplateChild<RepeatButton>("IncreaseRepeatButton", true, ref errors);
            if (this._elementIncreaseRepeatButton != null)
            {
                this.InitializeIncreaseRepeatButtonPart();
            }
            this._elementMiddleThumb = this.GetTemplateChild<Thumb>("MiddleThumb", false, ref errors);
            if (this._elementMiddleThumb != null)
            {
                this.InitializeMiddleThumbPart();
            }
            this._elementVerticalLowerThumb = this.GetTemplateChild<Thumb>("VerticalLowerThumb", false, ref errors);
            if (this._elementVerticalLowerThumb != null)
            {
                this.InitializeVerticalLowerThumbPart();
            }
            this._elementVerticalUpperThumb = this.GetTemplateChild<Thumb>("VerticalUpperThumb", false, ref errors);
            if (this._elementVerticalUpperThumb != null)
            {
                this.InitializeVerticalUpperThumbPart();
            }
            this._elementVerticalMiddleThumb = this.GetTemplateChild<Thumb>("VerticalMiddleThumb", false, ref errors);
            if (this._elementVerticalMiddleThumb != null)
            {
                this.InitializeVerticalMiddleThumbPart();
            }
            this._elementVerticalDecreaseRepeatButton = this.GetTemplateChild<RepeatButton>("VerticalDecreaseRepeatButton", false, ref errors);
            if (this._elementVerticalDecreaseRepeatButton != null)
            {
                this.InitializeVerticalDecreaseRepeatButtonPart();
            }
            this._elementVerticalIncreaseRepeatButton = this.GetTemplateChild<RepeatButton>("VerticalIncreaseRepeatButton", false, ref errors);
            if (this._elementVerticalIncreaseRepeatButton != null)
            {
                this.InitializeVerticalIncreaseRepeatButtonPart();
            }
            this._elementHorizontalTemplate = this.GetTemplateChild<Grid>("HorizontalTemplate", true, ref errors);
            this._elementVerticalTemplate = this.GetTemplateChild<Grid>("VerticalTemplate", false, ref errors);
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to RangeSlider.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateCommon(false);
                this.ChangeVisualStateFocus(false);
                this.OnAfterApplyTemplate();
            }
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as RangeSlider).ChangeVisualStateCommon(true);
        }

        private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as RangeSlider).ChangeVisualStateFocus(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider sender = d as RangeSlider;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnLowerValueChanged(double oldValue)
        {
            if (!this._isCoercingValue && this._isLoaded)
            {
                this.ValidateValueChanged(oldValue, this.LowerValue, true);
            }
        }

        protected virtual void OnLowerValueChanged(EventArgs e)
        {
            if (this.LowerValueChanged != null)
            {
                this.LowerValueChanged(this, e);
            }
        }

        private static void OnLowerValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider slider = d as RangeSlider;
            double oldValue = (double)e.OldValue;
            slider.OnLowerValueChanged(oldValue);
        }

        private void OnMaximumChanged(double oldValue)
        {
            if ((this.Maximum != oldValue) && this._isLoaded)
            {
                double num = Math.Max(this.Minimum, this.Maximum);
                this._isTrackUpdateAllowed = false;
                if (this.Maximum != num)
                {
                    this.Maximum = num;
                }
                this.LowerValue = Math.Min(this.LowerValue, this.Maximum);
                this.UpperValue = Math.Min(this.UpperValue, this.Maximum);
                this._isTrackUpdateAllowed = true;
                this.UpdateTrackLayout();
            }
        }

        private static void OnMaximumPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider slider = d as RangeSlider;
            double oldValue = (double)e.OldValue;
            slider.OnMaximumChanged(oldValue);
        }

        private void OnMiddleThumbDragDelta(System.Windows.Controls.Primitives.DragDeltaEventArgs e)
        {
            double num;
            if (this.Orientation == Orientation.Horizontal)
            {
                num = this.PixelsToUnits(e.HorizontalChange);
            }
            else
            {
                num = this.PixelsToUnits(-e.VerticalChange);
            }
            if (!double.IsNaN(num) && !double.IsInfinity(num))
            {
                this._middleDragValue += num;
                double minimum = this.Minimum;
                double num3 = this.Maximum - (this.UpperValue - this.LowerValue);
                double num4 = Math.Min(num3, Math.Max(minimum, this._middleDragValue));
                if (num4 != this.LowerValue)
                {
                    double num5 = Math.Abs((double)(this.LowerValue - num4));
                    this._isTrackUpdateAllowed = this._isEventFiringAllowed = false;
                    if (num4 < this.LowerValue)
                    {
                        this.LowerValue = Math.Round((double)(this.LowerValue - num5), 10);
                        this.UpperValue = Math.Round((double)(this.UpperValue - num5), 10);
                    }
                    else
                    {
                        this.UpperValue = Math.Round((double)(this.UpperValue + num5), 10);
                        this.LowerValue = Math.Round((double)(this.LowerValue + num5), 10);
                    }
                    this._isTrackUpdateAllowed = this._isEventFiringAllowed = true;
                    this.OnUpperValueChanged(EventArgs.Empty);
                    this.OnLowerValueChanged(EventArgs.Empty);
                    this.OnValueChanged(EventArgs.Empty);
                    this.UpdateTrackLayout();
                }
            }
        }

        private void OnMinimumChanged(double oldValue)
        {
            if ((this.Minimum != oldValue) && this._isLoaded)
            {
                double num = Math.Min(this.Maximum, this.Minimum);
                this._isTrackUpdateAllowed = false;
                if (this.Minimum != num)
                {
                    this.Minimum = num;
                }
                this.UpperValue = Math.Max(this.UpperValue, this.Minimum);
                this.LowerValue = Math.Max(this.LowerValue, this.Minimum);
                this._isTrackUpdateAllowed = true;
                this.UpdateTrackLayout();
            }
        }

        private static void OnMinimumPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider slider = d as RangeSlider;
            double oldValue = (double)e.OldValue;
            slider.OnMinimumChanged(oldValue);
        }

        private void OnOrientationChanged(object sender, PropertyChangedEventArgs<Orientation> e)
        {
            if (this._isLoaded)
            {
                if (this._elementHorizontalTemplate != null)
                {
                    this._elementHorizontalTemplate.Visibility = (this.Orientation == Orientation.Horizontal) ? Visibility.Visible : Visibility.Collapsed;
                }
                if (this._elementVerticalTemplate != null)
                {
                    this._elementVerticalTemplate.Visibility = (this.Orientation == Orientation.Horizontal) ? Visibility.Collapsed : Visibility.Visible;
                }
                this.UpdateTrackLayout();
            }
        }

        private static void OnOrientationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider sender = d as RangeSlider;
            if ((sender.OrientationChanged != null) && sender._throwOrientationChanged)
            {
                PropertyChangedEventArgs<Orientation> args = new PropertyChangedEventArgs<Orientation>
                {
                    OldValue = (Orientation)e.OldValue,
                    NewValue = (Orientation)e.NewValue
                };
                sender.OrientationChanged(sender, args);
            }
        }

        private void OnThumbDragDelta(System.Windows.Controls.Primitives.DragDeltaEventArgs e, bool lower)
        {
            double num;
            if (this.Orientation == Orientation.Horizontal)
            {
                num = this.PixelsToUnits(e.HorizontalChange);
            }
            else
            {
                num = this.PixelsToUnits(-e.VerticalChange);
            }
            if (!double.IsNaN(num) && !double.IsInfinity(num))
            {
                this._dragValue += num;
                double num2 = lower ? this.Minimum : this.LowerValue;
                double num3 = lower ? this.UpperValue : this.Maximum;
                double num4 = Math.Min(num3, Math.Max(num2, this._dragValue));
                if (lower && (num4 != this.LowerValue))
                {
                    this.LowerValue = num4;
                    this._middleDragValue = num4;
                }
                else if (!lower && (num4 != this.UpperValue))
                {
                    this.UpperValue = num4;
                }
            }
        }

        private void OnThumbDragStarted(Thumb sender, System.Windows.Controls.Primitives.DragStartedEventArgs e, bool lower)
        {
            sender.Focus();
            this._dragValue = lower ? this.LowerValue : this.UpperValue;
        }

        private void OnUpperValueChanged(double oldValue)
        {
            if (!this._isCoercingValue && this._isLoaded)
            {
                this.ValidateValueChanged(oldValue, this.UpperValue, false);
            }
        }

        protected virtual void OnUpperValueChanged(EventArgs e)
        {
            if (this.UpperValueChanged != null)
            {
                this.UpperValueChanged(this, e);
            }
        }

        private static void OnUpperValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RangeSlider slider = d as RangeSlider;
            double oldValue = (double)e.OldValue;
            slider.OnUpperValueChanged(oldValue);
        }

        protected virtual void OnValueChanged(EventArgs e)
        {
            if (this.ValueChanged != null)
            {
                this.ValueChanged(this, e);
            }
        }

        private double PixelsToUnits(double pixels)
        {
            double num = (this.Orientation == Orientation.Vertical) ? base.ActualHeight : base.ActualWidth;
            num -= (this.Orientation == Orientation.Vertical) ? this._elementVerticalLowerThumb.ActualHeight : this._elementLowerThumb.ActualWidth;
            num -= (this.Orientation == Orientation.Vertical) ? this._elementVerticalUpperThumb.ActualHeight : this._elementUpperThumb.ActualWidth;
            return ((pixels * (this.Maximum - this.Minimum)) / num);
        }

        private void SetCustomDefaultValues()
        {
            SizeChangedEventHandler handler = null;
            this._isTrackUpdateAllowed = true;
            this._isEventFiringAllowed = true;
            this.OrientationChanged += new EventHandler<PropertyChangedEventArgs<Orientation>>(this.OnOrientationChanged);
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                if (handler == null)
                {
                    handler = (s, e) => this.BeginInvoke(() => this.UpdateTrackLayout());
                }
                base.SizeChanged += handler;
            }
        }

        private void UpdateHorizontalTrackLayout()
        {
            if ((this._elementHorizontalTemplate.ColumnDefinitions != null) && (this._elementHorizontalTemplate.ColumnDefinitions.Count == 5))
            {
                this._elementHorizontalTemplate.ColumnDefinitions[0].Width = new GridLength(this.LowerValue - this.Minimum, GridUnitType.Star);
                this._elementHorizontalTemplate.ColumnDefinitions[2].Width = new GridLength(this.UpperValue - this.LowerValue, GridUnitType.Star);
                this._elementHorizontalTemplate.ColumnDefinitions[4].Width = new GridLength(this.Maximum - this.UpperValue, GridUnitType.Star);
            }
        }

        protected virtual void UpdateTrackLayout()
        {
            if (this._isLoaded && this._isTrackUpdateAllowed)
            {
                if ((this.Orientation == Orientation.Horizontal) && (this._elementHorizontalTemplate != null))
                {
                    this.UpdateHorizontalTrackLayout();
                }
                else if ((this.Orientation == Orientation.Vertical) && (this._elementVerticalTemplate != null))
                {
                    this.UpdateVerticalTrackLayout();
                }
            }
        }

        private void UpdateVerticalTrackLayout()
        {
            if ((this._elementVerticalTemplate.RowDefinitions != null) && (this._elementVerticalTemplate.RowDefinitions.Count == 5))
            {
                this._elementVerticalTemplate.RowDefinitions[4].Height = new GridLength(this.LowerValue - this.Minimum, GridUnitType.Star);
                this._elementVerticalTemplate.RowDefinitions[2].Height = new GridLength(this.UpperValue - this.LowerValue, GridUnitType.Star);
                this._elementVerticalTemplate.RowDefinitions[0].Height = new GridLength(this.Maximum - this.UpperValue, GridUnitType.Star);
            }
        }

        private void ValidateValueChanged(double oldValue, double newValue, bool lower)
        {
            this._isCoercingValue = true;
            double num = lower ? this.Minimum : this.LowerValue;
            double num2 = lower ? this.UpperValue : this.Maximum;
            double num3 = Math.Min(num2, Math.Max(num, newValue));
            if (newValue != oldValue)
            {
                if (lower)
                {
                    this.LowerValue = num3;
                    this.UpdateTrackLayout();
                    if ((num3 != oldValue) && this._isEventFiringAllowed)
                    {
                        this.OnLowerValueChanged(EventArgs.Empty);
                        this.OnValueChanged(EventArgs.Empty);
                    }
                }
                else
                {
                    this.UpperValue = num3;
                    this.UpdateTrackLayout();
                    if ((num3 != oldValue) && this._isEventFiringAllowed)
                    {
                        this.OnUpperValueChanged(EventArgs.Empty);
                        this.OnValueChanged(EventArgs.Empty);
                    }
                }
            }
            this._isCoercingValue = false;
        }

        // Properties
        public int Delay
        {
            get { return (int)GetValue(DelayProperty); }
            set { SetValue(DelayProperty, value); }
        }

        public Brush FocusBrush
        {
            get { return (Brush)GetValue(FocusBrushProperty); }
            set { SetValue(FocusBrushProperty, value); }
        }

        internal bool ForceMouseOver
        {
            get { return (bool)GetValue(ForceMouseOverProperty); }
            set { SetValue(ForceMouseOverProperty, value); }
        }

        public int Interval
        {
            get { return (int)GetValue(IntervalProperty); }
            set { SetValue(IntervalProperty, value); }
        }

        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            internal set { SetValue(IsFocusedProperty, value); }
        }

        public bool IsMouseOver
        {
            get { return (bool)GetValue(IsMouseOverProperty); }
            internal set { SetValue(IsMouseOverProperty, value); }
        }

        public double LowerValue
        {
            get { return (double)GetValue(LowerValueProperty); }
            set { SetValue(LowerValueProperty, value); }
        }

        public double Maximum
        {
            get { return (double)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }

        public double Minimum
        {
            get { return (double)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Orientation Orientation
        {
            get { return (Orientation)GetValue(OrientationProperty); }
            set { SetValue(OrientationProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        public double SmallValueChange
        {
            get { return (double)GetValue(SmallValueChangeProperty); }
            set { SetValue(SmallValueChangeProperty, value); }
        }

        public double UpperValue
        {
            get { return (double)GetValue(UpperValueProperty); }
            set { SetValue(UpperValueProperty, value); }
        }

        public Style ValidationDecoratorStyle
        {
            get { return (Style)GetValue(ValidationDecoratorStyleProperty); }
            set { SetValue(ValidationDecoratorStyleProperty, value); }
        }

        public double ValueChange
        {
            get { return (double)GetValue(ValueChangeProperty); }
            set { SetValue(ValueChangeProperty, value); }
        }
    }
}
